package com.ashlikun.okhttputils.http

import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.os.Looper
import com.ashlikun.okhttputils.http.callback.Callback
import com.ashlikun.okhttputils.http.request.HttpRequest
import com.google.gson.JsonNull
import com.google.gson.JsonParser
import com.google.gson.JsonPrimitive
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.UnsupportedEncodingException
import java.lang.reflect.GenericArrayType
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.net.URLConnection
import java.net.URLEncoder
import java.nio.charset.Charset
import java.util.regex.Pattern

/**
 * @author　　: 李坤
 * 创建时间: 2021.12.17 9:30
 * 邮箱　　：496546144@qq.com
 *
 * 功能介绍：用到的工具方法
 */


object HttpUtils {
    var UTF_8 = Charset.forName("UTF-8")

    val reUnicode = Pattern.compile("\\\\u([0-9a-zA-Z]{2,4})")//创建一个新的实例

    fun launchMain(job: suspend () -> Unit) {
        GlobalScope.launch(Dispatchers.Main) {
            job()
        }
    }

    /**
     * 是否是主线程
     */
    val isMainThread: Boolean
        get() = Looper.myLooper() == Looper.getMainLooper()

    /**
     * 运行到携程
     */
    fun launch(job: suspend () -> Unit) {
        GlobalScope.launch {
            job()
        }
    }

    /**
     * 获取文件的mime类型  Content-type
     */
    fun getMimeType(path: String): String {
        val fileNameMap = URLConnection.getFileNameMap()
        try {
            return fileNameMap.getContentTypeFor(URLEncoder.encode(path, "UTF-8"))
        } catch (e: UnsupportedEncodingException) {
            e.printStackTrace()
        }
        return HttpRequest.MEDIA_TYPE_STREAM.toString()
    }


    /**
     * 通过 ‘？’ 和 ‘/’ 判断文件名
     * http://mavin-manzhan.oss-cn-hangzhou.aliyuncs.com/1486631099150286149.jpg?x-oss-process=image/watermark,image_d2F0ZXJtYXJrXzIwMF81MC5wbmc
     */
    fun getUrlFileName(url: String): String {
        var filename = ""
        val strings = url.split("/").toTypedArray()
        for (string in strings) {
            if (string.contains("?")) {
                val endIndex = string.indexOf("?")
                if (endIndex != -1) {
                    filename = string.substring(0, endIndex)
                    return filename
                }
            }
        }
        if (strings.isNotEmpty()) {
            filename = strings[strings.size - 1]
        }
        return filename
    }


    fun isByteArray(type: Type) = type is GenericArrayType && type.genericComponentType == Byte::class.java

    /**
     * 获取回调里面的泛型
     */
    fun getType(mClass: Class<*>): Type {
        val types = mClass.genericSuperclass
        var parentypes: Array<Type?> //泛型类型集合
        if (types is ParameterizedType) {
            parentypes = types.actualTypeArguments
        } else {
            parentypes = mClass.genericInterfaces
            for (childtype in parentypes) {
                if (childtype is ParameterizedType) {
                    val rawType = childtype.rawType
                    //实现的接口是Callback
                    if (rawType is Class<*> && Callback::class.java.isAssignableFrom(
                            rawType
                        )
                    ) {
                        //Callback里面的类型
                        parentypes = childtype.actualTypeArguments
                    }
                }
            }
        }
        return parentypes.getOrNull(0) ?: throw RuntimeException("HttpSubscription  ->>>  ，请查看 " + mClass + "是否有泛型")
    }


    /**
     * unicode 转字符串
     */
    fun unicode2String(unicode: String): String {
        if (unicode.isEmpty()) return ""
        val m = reUnicode.matcher(unicode)
        val sb = StringBuffer(unicode.length)
        while (m.find()) {
            m.appendReplacement(sb, m.group(1).toInt(16).toChar().toString())
        }
        m.appendTail(sb)
        return sb.toString()
    }

    fun isJson(content: String) = jsonParser(content)?.run { true } ?: false

    fun jsonParser(content: String) = runCatching {
        val res = JsonParser().parse(content)
        if (res is JsonNull || res is JsonPrimitive) null
        else res
    }.getOrNull()

    @SuppressLint("MissingPermission")
    fun isNetworkAvailable(): Boolean {
        val connectivity = OkHttpManage.app?.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
        return runCatching {
            connectivity?.activeNetworkInfo?.state == NetworkInfo.State.CONNECTED
        }.getOrNull() ?: false
    }
}

inline fun String.isJson() = HttpUtils.isJson(this)
inline fun String.jsonParser() = HttpUtils.jsonParser(this)